package com.zensation.ticklemepanda;

import com.zensation.ticklemepanda.definition.GlobalDefine;
import com.zensation.ticklemepanda.util.TickleMePandaSharedPreference;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.CountDownTimer;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public class MainGameView extends SurfaceView {
	// =====================Variable define===================
	private boolean isThreadRunning = false;

	private static Bitmap background;
	private static Bitmap progressBarTheme;
	private static Bitmap progressBar;

	private Rect srcBG;
	private Rect dstBG;
	private Rect srcBar;
	private Rect dstBar;

	private int widthScreen;
	private int heightScreen;
	private int modeOfAnimal;

	private boolean isShakePhone = false;
	private boolean isActionDown = false;
	private boolean isActionUp = false;
	private boolean isActionMove = false;
	public static boolean isStart;
	private boolean isReset;
	private boolean isRestart = true;

	private int count = 1;
	private int watch_blinkConfig;
	private int cryConfig;
	private int snoozeConfig;
	private int giggleConfig;

	private TickleMePandaActivity mContext;
	private CountDownTimer myTimer;
	// =====================Class Define======================
	private GameLoopThread gameLoopThread;
	private SurfaceHolder holder;
	private MyAnimal myAnimal;
	private TickleMePandaSharedPreference funnyAnimalGameSharedPreference;

	public MainGameView(TickleMePandaActivity context) {
		super(context);
		mContext = context;
		// get the size of the screen
		widthScreen = context.getWindowManager().getDefaultDisplay().getWidth();
		heightScreen = context.getWindowManager().getDefaultDisplay().getHeight();
		initializeHolder();
		if (!checkValidConfigFile())
			Toast.makeText(mContext, "The config file is not correct.The gestures are default!",
					Toast.LENGTH_LONG).show();
	}

	public GameLoopThread getThread() {
		return gameLoopThread;
	}

	/**
	 * init Holder to control surfaceView
	 */
	private void initializeHolder() {
		holder = getHolder();
		holder.addCallback(new SurfaceHolder.Callback() {

			@Override
			public void surfaceDestroyed(SurfaceHolder holder) {
				gameLoopThread.setRunning(false);
				boolean retry = true;
				while (retry) {
					try {
						gameLoopThread.join();
						retry = false;
					} catch (InterruptedException e) {
						// try again shutting down the thread
					}
				}
				isThreadRunning = false;
			}

			@Override
			public void surfaceCreated(SurfaceHolder holder) {
				// initialize
				initialize();
				/* Control the thread of game */
				if (!isThreadRunning) {
					gameLoopThread = new GameLoopThread(MainGameView.this);
					gameLoopThread.setRunning(true);
					gameLoopThread.start();
				} else {
					// resumeGame();
				}
			}

			@Override
			public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

			}
		});
	}

	/**
	 * intialize object,variable
	 */

	private void initialize() {
		// panda watch -blink
		if (checkValidConfigFile())
			modeOfAnimal = watch_blinkConfig;
		else
			modeOfAnimal = GlobalDefine.WATCH_BLINK;
		if (background == null) {
			background = BitmapFactory.decodeResource(getResources(), R.drawable.background);
		}
		if (progressBarTheme == null)
			progressBarTheme = BitmapFactory.decodeResource(getResources(),
					R.drawable.progress_bar_theme);
		if (progressBar == null) {
			progressBar = BitmapFactory.decodeResource(getResources(), R.drawable.progress_bar);
		}
		if (myAnimal == null)
			myAnimal = new MyAnimal(mContext, modeOfAnimal, widthScreen, heightScreen);
		if (funnyAnimalGameSharedPreference == null)
			funnyAnimalGameSharedPreference = TickleMePandaSharedPreference.getInstance(mContext);
		// // set score value start game
		// funnyAnimalGameSharedPreference.putScoreValue(500);

		myAnimal.setCurrentFrameHeight(0);
		myAnimal.setCurrentFrameWidth(0);
		// start count down time
		startCountDownTimer();
	}

	@Override
	public void onDraw(Canvas canvas) {
		if (funnyAnimalGameSharedPreference.getScoreValue() >= GlobalDefine.WIN_SCORE) {
			gameLoopThread.setPause(true);
			mContext.sendMS(GlobalDefine.DIALOG_WIN_GAME);
		}

		drawBackGround(canvas);
		drawProgressBar(canvas);

		if (getShakePhone()) {
			isRestart = false;
			count = 1;
			if (myTimer != null)
				finishCountDownTimer();
			if (checkValidConfigFile()) {
				if (myAnimal.getModeOfAnimal() != GlobalDefine.SLEEP)
					myAnimal.setModeOfAnimal(cryConfig);
				else {
					myAnimal.setModeOfAnimal(GlobalDefine.WAKE_UP);
					myAnimal.setCurrentFrameHeight(0);
					myAnimal.setCurrentFrameWidth(0);
					startCountDownTimer();
				}
			} else {
				if (myAnimal.getModeOfAnimal() != GlobalDefine.SLEEP)
					myAnimal.setModeOfAnimal(GlobalDefine.CRY);
				else {
					myAnimal.setModeOfAnimal(GlobalDefine.WAKE_UP);
					myAnimal.setCurrentFrameHeight(0);
					myAnimal.setCurrentFrameWidth(0);
					startCountDownTimer();
				}
			}
			setShakePhone(false);
		}
		myAnimal.onDraw(canvas);
	}

	// draw background
	private void drawBackGround(Canvas canvas) {
		Paint paintBG = new Paint();
		paintBG.setAntiAlias(true);
		srcBG = new Rect(0, 0, background.getWidth(), background.getHeight());
		dstBG = new Rect(0, 0, widthScreen, heightScreen);
		canvas.drawBitmap(background, srcBG, dstBG, paintBG);
	}

	// draw progressBar
	private void drawProgressBar(Canvas canvas) {
		Paint paintBar = new Paint();
		paintBar.setAntiAlias(true);
		paintBar.setColor(Color.GREEN);
		// if (this.heightScreen < 470)
		// paintBar.setTextSize(20);
		// else if (this.heightScreen > 470 && this.heightScreen < 640)
		// paintBar.setTextSize(25);
		// else if (this.heightScreen > 640 && this.heightScreen < 960)
		// paintBar.setTextSize(30);
		// else
		// paintBar.setTextSize(35);
		//
		// // calculate score and percent of score to draw
		float temp1 = funnyAnimalGameSharedPreference.getScoreValue();
		float temp2 = GlobalDefine.WIN_SCORE;
		float numberPerCent = (temp1 / temp2) * 100;
		float indexProgressBar = (widthScreen - 20) * numberPerCent / 100;

		srcBar = new Rect(0, 0, progressBarTheme.getWidth(), progressBarTheme.getHeight());
		dstBar = new Rect(20, heightScreen * 5 / 100, widthScreen - 20,
				progressBarTheme.getHeight() + heightScreen * 5 / 100);
		Rect dstProgressBar = new Rect(20, heightScreen * 5 / 100, (int) indexProgressBar,
				progressBar.getHeight() + heightScreen * 5 / 100);
		Rect srcProgressBar = new Rect(0, 0, progressBar.getWidth(), progressBar.getHeight());
		// canvas.drawText((int) numberPerCent + "%", widthScreen / 2 - 10,
		// heightScreen * 5 / 100,
		// paintBar);
		canvas.drawBitmap(progressBarTheme, srcBar, dstBar, null);
		canvas.drawBitmap(progressBar, srcProgressBar, dstProgressBar, null);

	}

	public void setShakePhone(boolean b) {
		isShakePhone = b;
	}

	public boolean getShakePhone() {
		return isShakePhone;
	}

	@Override
	public boolean onTouchEvent(MotionEvent e) {
		switch (e.getAction()) {
		case MotionEvent.ACTION_DOWN:
			isActionDown = true;
			isActionMove = false;
			break;
		case MotionEvent.ACTION_MOVE:
			Point point = new Point();
			point.x = (int) e.getX();
			point.y = (int) e.getY();
			if (myAnimal.isCollision(point) || myAnimal.isCollisionPandaFeet(point)) {

				funnyAnimalGameSharedPreference.setGiggleByTap(false);
				// panda giggle
				if (checkValidConfigFile()) {
					if (myAnimal.getModeOfAnimal() == watch_blinkConfig)
						myAnimal.setModeOfAnimal(giggleConfig);
				} else {
					if (myAnimal.getModeOfAnimal() == GlobalDefine.WATCH_BLINK)
						myAnimal.setModeOfAnimal(GlobalDefine.GIGGLE);
				}
			}
			isActionMove = true;
			isActionDown = false;
			if (count > 0) {
				count = 1;
				if (myTimer != null) {
					finishCountDownTimer();
					myTimer.cancel();
					myTimer = null;
				}
			}
			break;
		case MotionEvent.ACTION_UP:
			if (myTimer != null) {
				finishCountDownTimer();
				myTimer.cancel();
				myTimer = null;
			}
			Point pointTouch = new Point();
			pointTouch.x = (int) e.getX();
			pointTouch.y = (int) e.getY();

			// tag to the face of panda
			if (myAnimal.isCollisionFace(pointTouch)) {
				if (checkValidConfigFile()) {
					if (myAnimal.getModeOfAnimal() == watch_blinkConfig)
						myAnimal.setModeOfAnimal(cryConfig);
					else if (myAnimal.getModeOfAnimal() == giggleConfig) {
						myAnimal.setModeOfAnimal(watch_blinkConfig);
						startCountDownTimer();
					} 
				} else {
					if (myAnimal.getModeOfAnimal() == GlobalDefine.WATCH_BLINK)
						myAnimal.setModeOfAnimal(GlobalDefine.CRY);
					else if (myAnimal.getModeOfAnimal() == GlobalDefine.GIGGLE) {
						myAnimal.setModeOfAnimal(GlobalDefine.WATCH_BLINK);
						startCountDownTimer();
					}
				}
				myAnimal.setCurrentFrameHeight(0);
				myAnimal.setCurrentFrameWidth(0);
			}// tag below neck of panda

			else if (myAnimal.isCollision(pointTouch) || myAnimal.isCollisionPandaFeet(pointTouch)) {
				funnyAnimalGameSharedPreference.setGiggleByTap(true);
				if (checkValidConfigFile()) {
					if (myAnimal.getModeOfAnimal() == GlobalDefine.SLEEP) {
						myAnimal.setModeOfAnimal(GlobalDefine.WAKE_UP);
						// wait for 5s from wake up animation to watch - blink
						// animation
						myAnimal.setCurrentFrameHeight(0);
						myAnimal.setCurrentFrameWidth(0);
						waitForWakeUp(5000);
					} else if (myAnimal.getModeOfAnimal() == giggleConfig
							|| myAnimal.getModeOfAnimal() == watch_blinkConfig) {
						funnyAnimalGameSharedPreference.setGiggleByTap(true);
						myAnimal.setModeOfAnimal(giggleConfig);
						// wait for 1s to start watch blink animation
						startCountDownTimer();
					} else if (myAnimal.getModeOfAnimal() == cryConfig) {
						myAnimal.setCurrentFrameHeight(0);
						myAnimal.setCurrentFrameWidth(0);
						myAnimal.setModeOfAnimal(watch_blinkConfig);
						// wait for 1s to start watch blink animation
						waitForWakeUp(1000);
					}
				} else { 
					if (myAnimal.getModeOfAnimal() == GlobalDefine.SLEEP) {
						myAnimal.setModeOfAnimal(GlobalDefine.WAKE_UP);
						myAnimal.setCurrentFrameHeight(0);
						myAnimal.setCurrentFrameWidth(0);
						// wait for 5s to start watch blink animation
						waitForWakeUp(5000);
					} else if (myAnimal.getModeOfAnimal() == GlobalDefine.GIGGLE
							|| myAnimal.getModeOfAnimal() == GlobalDefine.WATCH_BLINK) {
						funnyAnimalGameSharedPreference.setGiggleByTap(true);
						myAnimal.setModeOfAnimal(GlobalDefine.GIGGLE);
						// wait for 1s to start watch blink animation
						startCountDownTimer();
					} else if (myAnimal.getModeOfAnimal() == GlobalDefine.CRY) {
						myAnimal.setCurrentFrameHeight(0);
						myAnimal.setCurrentFrameWidth(0);
						myAnimal.setModeOfAnimal(GlobalDefine.WATCH_BLINK);
						
						// wait for 1s to start watch blink animation
						waitForWakeUp(1000);
					}
				}
			} else {
				if (checkValidConfigFile()) {
					if (myAnimal.getModeOfAnimal() == giggleConfig) {
						myAnimal.setModeOfAnimal(watch_blinkConfig);
						myAnimal.setCurrentFrameWidth(0);
					}
				} else if (myAnimal.getModeOfAnimal() == GlobalDefine.GIGGLE) {
					myAnimal.setModeOfAnimal(GlobalDefine.WATCH_BLINK);
					myAnimal.setCurrentFrameWidth(0);
				}
				startCountDownTimer();
			}

			isReset = true;
			gameLoopThread.setTimeLoop(150);
			isActionMove = false;
			break;
		default:
			break;
		}
		return true;
	}

	/*
	 * wait 2s from wake up animation to watch and blink animation for counting
	 * timer
	 */
	private void waitForWakeUp(int countTimer) {
		new CountDownTimer(countTimer, 1000) {

			@Override
			public void onTick(long millisUntilFinished) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onFinish() {
				// TODO Auto-generated method stub
				startCountDownTimer();
			}
		}.start();
	}

	/**
	 * create count down timer after 10s panda snooze or cry
	 * 
	 * @return
	 */
	private CountDownTimer createMyTimer() {
		return new CountDownTimer(10000, 1000) {

			@Override
			public void onTick(long millisUntilFinished) {
				// TODO Auto-generated method stub
				count++;
				if (count >= 10) {
					if (myTimer != null) {
						if (count > 0) {
							count = 1;
							finishCountDownTimer();
						}
						// set myAnimation cry or snooze
//						Random random = new Random();
//						int rd = random.nextInt(2);
						 int rd = 0;
						if (rd == 1) {
							// panda cry
							if (checkValidConfigFile())
								myAnimal.setModeOfAnimal(cryConfig);
							else
								myAnimal.setModeOfAnimal(GlobalDefine.CRY);
							gameLoopThread.setTimeLoop(150);
						} else if (rd == 0) {
							// panda snooze
							if (checkValidConfigFile())
								myAnimal.setModeOfAnimal(snoozeConfig);
							else
								myAnimal.setModeOfAnimal(GlobalDefine.SNOOZE);
							gameLoopThread.setTimeLoop(200);
						}

						myAnimal.setCurrentFrameHeight(0);
						myAnimal.setCurrentFrameWidth(0);
						isRestart = false;
					}
				}
			}

			@Override
			public void onFinish() {
				// TODO Auto-generated method stub
				if (isRestart)
					myTimer.start();
			}
		};
	}

	/**
	 * set count down timer for set the animation
	 */
	private void startCountDownTimer() {
		if (myTimer == null) {
			myTimer = createMyTimer();
		}
		myTimer.start();
	}

	/**
	 * stop my count down timer
	 */
	private void finishCountDownTimer() {
		isRestart = false;
		if (count > 0) {
			myTimer.onFinish();
			count = 1;
		}
	}

	public void resetGame() {
		// panda watch - blink
		if (checkValidConfigFile())
			myAnimal.setModeOfAnimal(watch_blinkConfig);
		else
			myAnimal.setModeOfAnimal(GlobalDefine.WATCH_BLINK);
		if (myTimer != null)
			finishCountDownTimer();
		startCountDownTimer();
	}

	private boolean checkValidConfigFile() {
		watch_blinkConfig = Integer.parseInt(mContext.getString(R.string.watch_blink));
		cryConfig = Integer.parseInt(mContext.getString(R.string.cry));
		giggleConfig = Integer.parseInt(mContext.getString(R.string.giggle));
		snoozeConfig = Integer.parseInt(mContext.getString(R.string.snooze));
		if (watch_blinkConfig < 1 || cryConfig < 1 || giggleConfig < 1 || snoozeConfig < 1
				|| watch_blinkConfig > 4 || cryConfig > 4 || giggleConfig > 4 || snoozeConfig > 4)
			return false;
		else
			return true;
	}
}
